package com.ruoyi.web.controller.system;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.SSL.domain.SslDomainRrVal;
import com.ruoyi.SSL.service.ISslApplyService;
import com.ruoyi.SSL.service.ISslDomainRrValService;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysMenuService;

/**
 * 首页 业务处理
 *
 * @author ruoyi
 */
@Controller
public class SysIndexController extends BaseController
{
    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private SysPasswordService passwordService;
    @Autowired
    private ISslApplyService applyService;
    @Autowired
    private ISslDomainRrValService rrValService;

    @Autowired
    private ISysNoticeService noticeService;

    @Value("${version}")
    private String version;


    // 系统首页
    @GetMapping("/index")
    public String index(ModelMap mmap)
    {
        // 取身份信息
        SysUser user = getSysUser();
        // 根据用户id取出菜单
        List<SysMenu> menus = menuService.selectMenusByUser(user);
        mmap.put("menus", menus);
        mmap.put("user", user);
        mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
        mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
        Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer"), true);
        Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView"), true);
        mmap.put("footer", footer);
        mmap.put("tagsView", tagsView);
        mmap.put("mainClass", contentMainClass(footer, tagsView));
        mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear());
        mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled());
        mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
        mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
        mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")));

        // 菜单导航显示风格
        String menuStyle = configService.selectConfigByKey("sys.index.menuStyle");
        // 移动端，默认使左侧导航菜单，否则取默认配置
        String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;

        // 优先Cookie配置导航菜单
        Cookie[] cookies = ServletUtils.getRequest().getCookies();
        for (Cookie cookie : cookies)
        {
            if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName()))
            {
                indexStyle = cookie.getValue();
                break;
            }
        }
        String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
        return webIndex;
    }

    // 锁定屏幕
    @GetMapping("/lockscreen")
    public String lockscreen(ModelMap mmap)
    {
        mmap.put("user", getSysUser());
        ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
        return "lock";
    }

    // 解锁屏幕
    @PostMapping("/unlockscreen")
    @ResponseBody
    public AjaxResult unlockscreen(String password)
    {
        SysUser user = getSysUser();
        if (StringUtils.isNull(user))
        {
            return AjaxResult.error("服务器超时，请重新登录");
        }
        if (passwordService.matches(user, password))
        {
            ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN);
            return AjaxResult.success();
        }
        return AjaxResult.error("密码不正确，请重新输入。");
    }

    // 切换主题
    @GetMapping("/system/switchSkin")
    public String switchSkin()
    {
        return "skin";
    }

    // 切换菜单
    @GetMapping("/system/menuStyle/{style}")
    public void menuStyle(@PathVariable String style, HttpServletResponse response)
    {
        CookieUtils.setCookie(response, "nav-style", style);
    }

    // 系统介绍
    @GetMapping("/system/main")
    public String main(HttpServletRequest request,ModelMap mmap)
    {
        //同步平台信息
        configService.syncPlatform();
        //同步域名验证信息
        List<SslDomainRrVal> rrValList = rrValService.selectSslDomainRrValList(new SslDomainRrVal());
        for (SslDomainRrVal domainRrVal : rrValList) {
            AjaxResult aj = applyService.getDomainRrVal(domainRrVal.getDomainTxt(), domainRrVal.getRrVal());
            if(aj.isSuccess()){
                rrValService.deleteSslDomainRrValById(domainRrVal.getId());
                Console.log("同步域名验证信息成功，同步域名：{}", domainRrVal.getDomainTxt());
            }
        }
        //判断是否已经配置了请求appId和秘钥
        String appId = configService.selectConfigByKey("api.appId");
        String appSecret = configService.selectConfigByKey("api.appSecret");
        if(StringUtils.isBlank(appId) || StringUtils.isBlank(appSecret)){
            mmap.put("platFormInfo", null);
        }else{
            AjaxResult aj = configService.getPlatformInfoByAppId(CommUtils.REQ_API_URI, appId, appSecret);
            if(!aj.isSuccess()){
                mmap.put("platFormInfo", null);
                mmap.put("error", aj.get("msg").toString());
            }else{
                mmap.put("platFormInfo", JSONUtil.parseObj(aj.get("data")));
            }
            SysConfig configInfo = new SysConfig();
            configInfo.setConfigKey("script.token");
            List<SysConfig> configList = configService.selectConfigList(configInfo);
            if(configList != null && configList.size() > 0){
                configInfo = configList.get(0);
                if(StrUtil.isBlank(configInfo.getConfigValue())){
                    configInfo.setConfigValue(RandomUtil.randomStringWithoutStr(18, "4"));
                    //保存数据
                    configService.updateConfig(configInfo);
                }
            }
        }
        AjaxResult aj = noticeService.getSerNoticeData();
        if(aj.isSuccess()){
            mmap.put("noticeList", JSONUtil.toList(JSONUtil.toJsonStr(aj.get("data")), SysNotice.class));
        }else{
            mmap.put("noticeList", null);
        }
        mmap.put("version", RuoYiConfig.getVersion());
        return "main";
    }

    @ResponseBody
    @GetMapping("/system/notice/checkVersion")
    public AjaxResult checkVersion(){
        AjaxResult aj = applyService.getNewVersion();
        if(aj.isSuccess()){
            if(!version.equals(String.valueOf(aj.get("data")))) {
                aj.put("oldVer", version);
                return aj;
            }
        }
        return AjaxResult.error("您已经是最新版！");
    }

    @ResponseBody
    @GetMapping("/system/notice/aswwd")
    public AjaxResult aswwd(String scheme,String serverName, String serverPort){
        SysConfig configInfo = new SysConfig();
        configInfo.setConfigKey("self.domain");
        List<SysConfig> configList1 = configService.selectConfigList(configInfo);
        String fullUrl = scheme + "//" + serverName;
        if (StrUtil.isNotBlank(serverPort)) { // 通常80是http的默认端口，443是https的默认端口
            fullUrl +=":"+ serverPort;
        }
        if(configList1 != null && configList1.size() > 0){
            configInfo = configList1.get(0);
            configInfo.setConfigValue(fullUrl);
            configService.updateConfig(configInfo);
        }else{
            configInfo.setConfigName("本平台域名");
            configInfo.setConfigKey("self.domain");
            configInfo.setConfigValue(fullUrl);
            //插入数据
            configService.insertConfig(configInfo);
        }
        //系统版本
        configInfo.setConfigKey("system.version");
        configList1 = configService.selectConfigList(configInfo);
        if(configList1 != null && configList1.size() > 0){
            configInfo = configList1.get(0);
            if(!configInfo.getConfigValue().equals(version)){
                configInfo.setConfigValue(version);
                configService.updateConfig(configInfo);
            }
        }else{
            configInfo.setConfigName("本平台域名");
            configInfo.setConfigKey("system.version");
            configInfo.setConfigValue(version);
            //插入数据
            configService.insertConfig(configInfo);
        }
        return AjaxResult.success();
    }

    // content-main class
    public String contentMainClass(Boolean footer, Boolean tagsView)
    {
        if (!footer && !tagsView)
        {
            return "tagsview-footer-hide";
        }
        else if (!footer)
        {
            return "footer-hide";
        }
        else if (!tagsView)
        {
            return "tagsview-hide";
        }
        return StringUtils.EMPTY;
    }

    // 检查初始密码是否提醒修改
    public boolean initPasswordIsModify(Date pwdUpdateDate)
    {
        Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
        return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
    }

    // 检查密码是否过期
    public boolean passwordIsExpiration(Date pwdUpdateDate)
    {
        Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
        if (passwordValidateDays != null && passwordValidateDays > 0)
        {
            if (StringUtils.isNull(pwdUpdateDate))
            {
                // 如果从未修改过初始密码，直接提醒过期
                return true;
            }
            Date nowDate = DateUtils.getNowDate();
            return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
        }
        return false;
    }
}
